package com.jpaAutoProcess.utils;

import lombok.NonNull;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * TODO:暂时没使用
 * @author cc
 * @date 2022/8/22 17:46
 * @Description : 数据库字段转换成实体类核心工具
 */

public class SqlConvertEntityUtil {

  /**
   * 获取字段名k和对应的值value
   *
   * @param fieldlist 字段集合
   * @param valuelist 值集合
   * @author cc
   * @return List<HashMap<String, Object>>
   */
  public static List<HashMap<String, Object>> getfieldAndValueMap(List<String> fieldlist, List<Object> valuelist) {
    List<HashMap<String, Object>> fieldAndValueMap = new ArrayList<>();
    valuelist.stream().forEach(row -> {
      //获取有多少组数据
      if (row.getClass().isArray()) {
        Object[] column = (Object[]) row;
        int i = 0;
        HashMap<String, Object> map = new HashMap<>();
        //获取每列的元素
        for (Object o2 : column) {
          map.put(fieldlist.get(i++), o2);
        }
        fieldAndValueMap.add(map);
      }
    });

    return fieldAndValueMap;
    //替代方法
//        for (Object o : resultList) {
//            if (o.getClass().isArray()) {
//                Object[] obj = (Object[]) o;
//                int i = 0;
//                HashMap<String, Object> map = new HashMap<>();
//                for (Object o2 : obj) {
//                    map.put(strings.get(i++), o2);
//                }
//                fieldAndValueMap.add(map);
//            }
//        }

  }

  /**
   * 获取字段集合
   * 注：select截止于from之前
   *
   * @param sql sql语句 例：select id as pid,name as fname from xx where
   * @author cc
   */
  public static List<String> getSelectStringToList(StringBuilder sql) {
    if (sql.toString().contains("from")) {
      sql = new StringBuilder(sql.toString().split("from")[0]);
    }
    List<String> elementList = new ArrayList<>();
    String[] childelement = sql.toString().split("as");

    try {
      for (int i = 0; i < childelement.length - 1; i++) {
        String tempString = childelement[i + 1];
        if (!tempString.contains(",")) {
          elementList.add(tempString.trim());
        } else {
          elementList.add(tempString.substring(0, tempString.indexOf(",")).trim());
        }
      }
      return elementList;
    } catch (Exception e) {
      throw new RuntimeException(String.format("sql语句错误。当前sql语句为:{%s}",sql));
    }
  }

  /**
   * 获取目标类
   *
   * @param fieldAndValue 字段和值 map
   * @param targetClass   目标类
   * @author cc
   */
  public static Object reflectionTargetClass(HashMap<String, Object> fieldAndValue, Class targetClass) throws IllegalAccessException, InstantiationException {
    Object o = targetClass.newInstance();
    Field[] declaredFields = targetClass.getDeclaredFields();
    for (Field declaredField : declaredFields) {
      fieldAndValue.forEach((k, v) -> {
        if (declaredField.getName().equals(k)) {
          try {
            declaredField.setAccessible(true);
            declaredField.set(o, v);
          } catch (Exception e) {
            String.format("字段[%s] 的所属类型与数据库类型不匹配", k);
            throw new RuntimeException(String.format("[%s]字段的所属类型与数据库类型不匹配", k));
          }
        }
      });
    }
    return o;
  }

  public static Class getSuperclassTypeParameter(Class superclass) {

    Type genericSuperclass = superclass.getGenericSuperclass();
    if (genericSuperclass instanceof Class) {
      throw new RuntimeException("泛型获取失败");
    } else {
      ParameterizedType parameterized = (ParameterizedType) genericSuperclass;
      Class entityClass = (Class) parameterized.getActualTypeArguments()[0];
      return entityClass;
    }
  }

  /**
   * 凭借数据库需要的select
   * @author C.c
   * @since 2022-08-23 15:27
   * @param select
   * @return StringBuilder
  **/

  public static StringBuilder spellSelect(StringBuilder select){

    int start = select.toString().indexOf("select")+6;
    int end=select.toString().length();
    if (select.toString().contains("from")){
       end= select.toString().indexOf("from");
    }
    String substring = select.toString().substring(start, end).trim();

    String[] sonSelect = substring.split(",");

    StringBuilder resultString = new StringBuilder("Select ");
    for (String s : sonSelect) {
      if (s.contains("as")){
        String[] tempString = s.split("as");
        resultString.append(tempString[0].trim()).append(" as ").append(tempString[1].trim());
      } else if (s.contains(" ")){
        String[] tempString = s.split(" ");
        resultString.append(tempString[0]).append(" as ").append(tempString[1]);
      }else {
        select.append(s).append(" as ").append(s);
      }
      resultString.append(",");
    }
    resultString = new StringBuilder(resultString.substring(0,resultString.toString().lastIndexOf(","))).append(" ");
    return resultString;
  }


  /**
   * 初始化sql语句
   *
   * @param select select语句
   * @param from   from语句
   * @param where  where语句
   * @return String
   * @author C.c
   * @since 2022-08-23 08:44
   **/
  public static StringBuilder initSql(@NonNull StringBuilder select, @NonNull StringBuilder from, StringBuilder where) {
    select = SqlConvertEntityUtil.spellSelect(select);
    select.append(from);
    if (where != null) {
      select.append(" ").append(where);
    }
    return select;
  }
}
